import java.util.List;
import java.util.Scanner;

import asset.Define;
import asset.RegOrder;

/**
 * Attribute<p/>
 * formars : DisAssemble for Mars
 */
public class DisAssembler {
    
    private static boolean formars = false;

    public static void outConfig(boolean forMars) {
        DisAssembler.formars = forMars; 
    }

    //private inner decoder for R,I,J
    public static String rDecode(String codeString) throws Exception {
        List<String> tempList = RegOrder.splits(codeString, 6,11,16,21,26,32);
        String rs = Define.getRegName(Integer.valueOf(tempList.get(1),2));
        String rt = Define.getRegName(Integer.valueOf(tempList.get(2),2));
        String rd = Define.getRegName(Integer.valueOf(tempList.get(3),2));
        int shamet = Integer.valueOf(tempList.get(4),2);
        String funct = Define.getInstString(tempList.get(5),false);
        int format = Define.getRformat(funct);
        switch (format) {
            case 0b111:
                return String.format("%-9s %-3s, %-3s, %-3s",funct,rd,rs,rt);
            case 0b011:
                return String.format("%-9s %-3s, %-3s, %#-3x",funct,rd,rt,shamet);
            case 0b100:
                return String.format("%-9s %-3s",funct,rs);
            case 0b110:
                return String.format("%-9s %-3s, %-3s",funct,rs,rt);
            case 0b001:
                return String.format("%-9s %-3s",funct,rd);
            case 0b000:
                return funct;
            default:
                return "nop";
        }
    }

    public static String iDecode(String codeString) throws Exception {
        List<String> tempList = RegOrder.splits(codeString, 6,11,16,32);
        String opcode = tempList.get(0);
        String rs = Define.getRegName(Integer.valueOf(tempList.get(1),2));
        String rt = Define.getRegName(Integer.valueOf(tempList.get(2),2));
        String imm = Define.zeroExtStr("0b" + codeString,16,16);
        String funct = Define.getInstString(opcode);
        String format = Define.getIformat(funct);
        if (format.equals("cal")) {
            String minus = imm;
            if (funct.equals("slti") || funct.equals("addi")) {
                minus = Define.sigExtStr("0b" + tempList.get(3),16,16);
            }
            return String.format("%-9s %-3s, %-3s, %s",
                funct,rt,rs,formars ? minus : imm);
        }
        else if (format.equals("load") || format.equals("store")) {
            String minus = Define.sigExtStr("0b" + tempList.get(3),16,16);
            return String.format("%-9s %-3s, %s(%s)",
                funct,rt,formars ? minus : imm,rs);
        }
        else if (format.equals("branch")) {
            String minus = Define.sigExtStr("0b" + tempList.get(3),16,16);
            return String.format("%-9s %-3s, %-3s, %s",
                funct,rs,rt,formars ? minus : imm);
        }
        else if (format.equals("imm")) {
            return String.format("%-9s %-3s, %s",
                funct,rt,imm);
        }
        return "nop";
    }

    public static String jDecode(String codeString) throws Exception {
        List<String> tempList = RegOrder.splits(codeString,6,32);
        String funct = Define.getInstString(tempList.get(0));
        String plus = Define.zeroExtStr("0b" + tempList.get(1),26,26);
        String minus = Define.sigExtStr("0b" + tempList.get(1),26,26);
        return String.format("%-9s %s",
            funct,formars ? minus : plus);
    }

    /**decode */
    public static String decode(String codeString) throws Exception {
        byte type = Define.getInstType(codeString.substring(0,6));
        switch (type) {
            case 0:
                return rDecode(codeString);
            case 1:
                return iDecode(codeString);
            default:
                return jDecode(codeString);
        }
    }

    private static Scanner scanner = new Scanner(System.in);

    public static void main(String[] args) throws Exception {
        if (args != null && args.length != 0) {
            outConfig(true);
        }
        String line;
        while (true) {
            line = scanner.nextLine();
            while (line.equals("")) {
                line = scanner.nextLine();
            }
            if (line.equals("exit")) {
                scanner.close();
                break;
            }
            System.out.println(decode(RegOrder.filterMachineCode(line)));
        }
    }
}
